#include "oled_spi.h"


//写oled spi的ss
void oled_spi_write_ss(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

//初始化
void oled_spi_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	SPI_InitTypeDef SPI_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE);
	
	//NS 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; 
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//SCK MOSI 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; 
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//MISO
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; 
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//SPI
	//配置SCK时钟频率-->目前72M / 128 ~~ 500KHZ;
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;  
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//8位
	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;////双线全双工
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;  //高位先行
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;  //决定当前设备是SPI的主机还是从机
	
	//模式0
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; //第几个边沿采样
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low ;  //空闲状态默认低电平
	SPI_InitStruct.SPI_CRCPolynomial = 7;
	
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;   //软件NSS
	SPI_Init(SPI1,&SPI_InitStruct);
	
	//4、开始控制
	SPI_Cmd(SPI1,ENABLE);
	//默认给SS输出高电平,默认不选中从机
	oled_spi_write_ss(1);
}

//起始信号，置低电平
void oled_spi_start(void)
{
	oled_spi_write_ss(0);
}

//终止信号，置高电平
void oled_spi_stop(void)
{
	oled_spi_write_ss(1);
}


//交换一个字节(SPI核心部分)，模式0
uint8_t oled_spi_swapbyte(uint8_t ByteSend)
{
//等待TXE为1，发送寄存器为空
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);  //标志位等于SET后就会跳出循环
	
	//软件写入数据至SPI_DR
	SPI_I2S_SendData(SPI1, ByteSend);  //传入ByteSend后，ByteSend写入到TDR，之后ByteSend自动转入到移位寄存器，一旦移位寄存器有数据，时序波形自动产生
	
	//等待RXNE为1，表示接收到了数据，同时表示发送时序产生完成
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);  //标志位等于SET后就会跳出循环
	
	//读取数据
	return SPI_I2S_ReceiveData(SPI1);
}

